from fileinput import filename

from app.routes.analysis.StandardInspect import file_path
from ..base import base
from flask import Flask, Response, request

from http import HTTPStatus
import requests
import logging
import json  # 新增json模块导入
import PyPDF2
import os
import hashlib
import docx
import openpyxl
from  .analysis import StandardInspect
import logging
from .analysis import DocumentInspection  # 在顶部导入
from .analysis import DocmentInspection
import json

logger = logging.getLogger(__name__)
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'D:\\AIToolsWeb\\authbase2\\upload'
app.config['ALLOWED_EXTENSIONS'] = {'doc', 'docx', 'pdf', 'xlsx'}
app.session_id = None

IP = "20.1.57.46"
PORT = "21180"
APP_KEY = "aeb43a70b2ac4ea2a93c49bfcedee397"
agentId = "06905cda-2712-4a6f-838a-2008de46d0e1"
agentVersion = "1746694226016"


def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']



def process_pdf(filepath):
    """处理PDF文件"""
    with open(filepath, 'rb') as file:
        reader = PyPDF2.PdfReader(file)
        return "\n".join([page.extract_text() for page in reader.pages])


def process_word(filepath, promptStr):
    """处理Word文档"""
    doc_content = DocmentInspection.read_docx_tables(filepath)
    content = json.dumps(doc_content, ensure_ascii=False, indent=2)
    problem_count = 0
    if isinstance(doc_content, dict) and 'sections' in doc_content:
        problem_count = sum(len(section.get('tables', [])) for section in doc_content['sections'])
    return f"文档内容：{content}\n\n核查问题（共发现{problem_count}个问题）\n\n用户问题：{promptStr}", problem_count


def process_excel(filepath, promptStr=""):
    """处理Excel文件并返回HeCha数据（只进行数据模型检查）"""
    try:
        # 修改为直接调用验证函数
        from .analysis.ShuJuHeCha import validate_excel_physical_model

        # 只进行数据模型验证
        return validate_excel_physical_model([filepath])

    except Exception as e:
        logger.error(f"Excel文件处理异常: {str(e)}")
        raise


def event_stream(response):
    # for response in responses:
    if response["code"] == "000000":
        yield f'data: {json.dumps(response)}\n\n'  # SSE格式要求
    else:
        yield f'data: {json.dumps(response)}\n\n'  # SSE格式要求


@base.route('/smart/qainternal/chatstream', methods=['GET'])
def qainternal_chatStream():
    # agentId = request.args.get('agentId')
    # agentVersion = request.args.get('agentVersion')
    sessionId = request.args.get('sessionId')
    promptStr = request.args.get('text')
    files = request.args.get('files')
    filename = request.args.get('ext')  #ext存放文件名称
    promptContent = promptStr

    if files:
        files = files.split(",")

    header_str = ""
    inspect_errors = ""
    hecha_data = ""
    problem_count = 0
    if filename:
        upload_dir = app.config['UPLOAD_FOLDER']
        filepath = os.path.join(upload_dir, filename)
        try:
            # 读取文件内容
            if filename.endswith('.pdf'):
                with open(filepath, 'rb') as file:
                    reader = PyPDF2.PdfReader(file)
                    content = "\n".join([page.extract_text() for page in reader.pages])
            elif filename.endswith(('.doc', '.docx')):
                doc_content = DocmentInspection.read_docx_tables(filepath)
                content = json.dumps(doc_content, ensure_ascii=False, indent=2)
                if isinstance(doc_content, dict) and 'sections' in doc_content:
                    problem_count = sum(len(section.get('tables', [])) for section in doc_content['sections'])
                # 保持与Excel相同的参数结构
                promptContent = f"文档内容：{content}\n\n核查问题 ）\n\n用户问题：{promptStr}"
            elif filepath.endswith('.xlsx'):
                if filename.startswith('基线表'):
                    problem_count, hecha_data = process_excel(filepath, promptStr)
                else:
                    # 解析Excel文件
                    wb = openpyxl.load_workbook(filepath)
                    text = []
                    headers = []
                    for sheet in wb:
                        # 提取表头
                        try:
                            first_row = next(sheet.iter_rows(values_only=True))
                            headers.extend([str(h) for h in first_row if h is not None and h != ''])
                            # 提取所有行数据
                            for row in sheet.iter_rows(values_only=True):
                                text.append('\t'.join(map(str, row)))
                        except Exception as e:
                            pass
                    content = '\n'.join(text)
                    # 拼接表头为逗号分隔字符串
                    header_str = ','.join(headers)
                    inspect_errors = StandardInspect.read_excel_file(filepath)
                    # 最终优化统计逻辑
                    problem_count = 0
                    if inspect_errors:
                        import re
                        # 匹配带括号或花括号的条目结构
                        pattern = re.compile(r'([({].*?[})])')

                        if isinstance(inspect_errors, str):
                            # 提取所有有效条目
                            entries = pattern.findall(inspect_errors)
                            # 过滤空条目并去重
                            entries = list(set([e.strip(" (){}") for e in entries if e]))
                            problem_count = len(entries)
                            # 增强调试日志
                            logger.debug(f"精确条目统计 - 总数:{problem_count} 有效条目:{entries}")
                        elif isinstance(inspect_errors, list):
                            problem_count = len(inspect_errors)
                        elif isinstance(inspect_errors, dict):
                            problem_count = len(inspect_errors.get('errors', []))
            else:  # .doc or other text files
                with open(filepath, 'r', encoding='utf-8') as file:
                    content = file.read()

            if hecha_data:
                promptContent = f"核查问题：{hecha_data}（共发现{problem_count}个问题）\n\n 用户咨询问题：{promptStr} ,输出格式要清晰明了，多次输出且格式保持不变"

            elif header_str:
                promptContent = f"表头内容：{header_str}\n\n核查问题（共发现{problem_count}个问题）:{inspect_errors}\n\n用户咨询问题：{promptStr}"
            else:
                # 修正变量引用错误
                promptContent = f"核查问题（共发现{problem_count}个问题）:{inspect_errors}\n\n用户咨询问题：{promptStr}"
        except Exception as e:
            return {'error': f'文件读取失败：{str(e)}'}, 500


    # 保持原有日志记录方式
    logger.error("promptContent:" + promptContent + "\n\n")  # 原有日志代码不变
    # 新增Word文档解析日志
    if filename and filename.endswith(('.doc', '.docx')):
        logger.info(f"Word文档解析完成，共发现{problem_count}个待核查问题")

    response = chat_session(agentId, agentVersion, sessionId, promptContent, files)
    return Response(
        event_stream(response),
        mimetype='text/event-stream'
    )

@base.route('/smart/qainternal/upload', methods=['POST'])
def qainternalupload():
    try:
        if 'file' not in request.files:
            return {'error': '未选择文件'}, 400
        file = request.files['file']
        if not (file and allowed_file(file.filename)):
            return {'error': '不允许的文件类型'}, 400

        # 分离文件名和扩展名
        # _, ext = os.path.splitext(file.filename)

        files = {'file': (file.filename, file.stream, file.mimetype)}
        # agentId = request.form.get('agentId')
        # agentVersion = request.form.get('agentVersion')
        sessionId = request.form.get('sessionId')

        url = "http://" + IP + ":" + PORT + "/lmp-cloud-ias-server/api/session/file/upload"
        payload = {
            "agentId": f'{agentId}',
            "agentVersion": f'{agentVersion}',
            "sessionId": f'{sessionId}'
        }
        headers = {
            'User-Agent': 'Mozilla/5.0',
            'Authorization': f'{APP_KEY}'
        }
        response = requests.request("POST", url, files=files, headers=headers, data=payload)

        # 解析响应JSON
        response_data = response.json()
        fileId = response_data.get("data").get('fileId')  # 根据实际响应结构调整字段名

        # 确保上传目录存在
        upload_dir = app.config['UPLOAD_FOLDER']
        try:
            os.makedirs(upload_dir, exist_ok=True)
        except Exception as e:
            return {'error': f'创建目录失败：{str(e)}'}, 500

        try:
            file.stream.seek(0)
            filepath = os.path.join(upload_dir, file.filename)
            file.save(filepath)
        except Exception as e:
            return {'error': f'文件保存失败：{str(e)}'}, 500

        # 在响应对象中添加扩展名字段
        response_data["data"]['ext'] = file.filename # 去掉扩展名前缀的点
        return response_data

    except Exception as e:
        logger.error(f"文件上传异常: {str(e)}")
        return {"error": "服务器内部错误"}, 500


@base.route('/smart/qainternal/startsession', methods=['GET'])
def start_session():
    try:
        # agentId = request.args.get('agentId')
        # agentVersion = request.args.get("agentVersion")
        url = "http://" + IP + ":" + PORT + "/lmp-cloud-ias-server/api/session/create"
        payload = json.dumps({
            "agentId": f'{agentId}',
            "agentVersion": f'{agentVersion}'
        }, ensure_ascii=False).encode("utf-8")

        headers = {
            'User-Agent': 'Mozilla/5.0',
            'Content-Type': 'application/json',
            'Authorization': f'{APP_KEY}'
        }
        logger.error(f"API请求头信息：{str(headers)}")
        logger.error(f"url ：{str(url)}")
        logger.error(f"payload ：{str(payload)}")
        response = requests.request("POST", url, headers=headers, data=payload)
        logger.error(f"response ：{repr(response)}")
        # 处理正常响应
        response_data = response.json()
        logger.error(f"response_data ：{str(response_data)}")
        if response_data['code'] == '000000':
            logger.error("sessionId %s", response_data['data']['sessionId'])
            return response_data['data']['sessionId']
        # 处理业务异常
        logger.error(f"创建会话异常: {response_data.get('message')}")
        return -1
    except requests.exceptions.RequestException as e:
        logger.error(f"创建会话异常: {str(e)}")
        return -1
    except Exception as e:
        logger.error(f"创建会话异常: {str(e)}")
        return -1


def chat_session(agentId, agentVersion, sessionId, text, files):
    try:
        url = "http://" + IP + ":" + PORT + "/lmp-cloud-ias-server/api/session/run"
        payload = json.dumps({
            "agentId": f'{agentId}',
            "agentVersion": f'{agentVersion}',
            "sessionId": f'{sessionId}',
            "text": f'{text}',
            "stream": False,
            "files": files  # Array[]文件ID
            # "metadata":metadata     #Jsonobject
        }, ensure_ascii=False)
        headers = {
            'User-Agent': 'Mozilla/5.0',
            'Content-Type': 'application/json',
            'Authorization': f'{APP_KEY}'
        }
        response = requests.request("POST", url, headers=headers, data=payload.encode("utf-8"))
        return response.json()
    except Exception as e:
        logger.error(f"智能体会话异常: {str(e)}")
        return ""


def del_session(sessionId, agentId, agentVersion, APP_KEY):
    try:
        url = "http://" + IP + ":" + PORT + "/lmp-cloud-ias-server/api/session/delete"
        payload = json.dumps({
            "sessionId": f'{sessionId}',
            "agentId": f'{agentId}',
            "queryagentVersion": f'{agentVersion}'
        }, ensure_ascii=False)
        headers = {
            'User-Agent': 'Mozilla/5.0',
            'Content-Type': 'application/json',
            'Authorization': f'{APP_KEY}'
        }
        response = requests.request("POST", url, headers=headers, data=payload.encode("utf-8"))
        # 处理正常响应
        response_data = response.json()
        return response_data
    except Exception as e:
        logger.error(f"删除会话异常: {str(e)}")
        return ""


if __name__ == '__main__':
    app.run(debug=True, port=5000)
